
package au.com.lastweekend.openjaws.plugins;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import au.com.lastweekend.openjaws.api.Readings;
import au.com.lastweekend.openjaws.api.WeatherPlugin;
import au.com.lastweekend.openjaws.api.WeatherPluginException;

/**
 * Reports 1 reading every X seconds.
 * 
 * @author grant@lastweekend.com.au
 * @version $Id: codetemplates.xml,v 1.2 2005/01/22 06:53:11 ggardner Exp $
 */
public class ReportableReadingsPlugin implements WeatherPlugin {

    private Readings accumulatedReadings = new Readings();
    private long lastReadingTimeMillis = 0;
    private long reportableTimeMillis = 2 * 60 * 1000;
    private WeatherPlugin decorated;
    private boolean enabled = true;
    private static final Logger LOG = LoggerFactory.getLogger(ReportableReadingsPlugin.class);

    public ReportableReadingsPlugin(WeatherPlugin decorated) {

        this.decorated = decorated;

    }

    public void process(Readings readings) throws WeatherPluginException {

        if (isEnabled()) {
            long readingTimeMillis = readings.getReadingTime().getTime();

            LOG.debug("Accumulating");
            accumulatedReadings.accumulate(readings);

            if (readingTimeMillis - lastReadingTimeMillis > reportableTimeMillis) {
                LOG.debug("Processing accumulated readings");
                decorated.process(accumulatedReadings);
                accumulatedReadings.clean();
                lastReadingTimeMillis = readingTimeMillis;
            }

        } else {
            decorated.process(readings);
        }

    }

    public boolean isEnabled() {

        return enabled;
    }

    /**
     * 
     * @param enabled
     *            true to enable this plugin
     */
    public void setEnabled(boolean enabled) {

        this.enabled = enabled;
    }

    /**
     * 
     * @param reportingPeriod
     *            minimum time between readings, in seconds
     */
    public void setReportingPeriod(long reportingPeriod) {

        this.reportableTimeMillis = reportingPeriod * 1000;

    }

    /**
     * @param reportableReadings
     *            the readings object which will be used to accumulate readings. Probably only useful for testing
     */
    void setAccumulatedReadings(Readings reportableReadings) {

        this.accumulatedReadings = reportableReadings;

    }

}
